<template>
    <div class="consumption-chart-container">
        <div ref="chartContainer" class="chart-container"></div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
import * as d3 from 'd3';

const props = defineProps({
    // 图表数据
    chartData: {
        type: Array,
        required: true,
        default: () => []
    },
    // 图表标题
    title: {
        type: String,
        default: ''
    }
});

const chartContainer = ref(null);
let svg = null;
let chart = null;

// 创建图表
const createChart = () => {
    if (!chartContainer.value || props.chartData.length === 0) return;

    // 清空容器
    d3.select(chartContainer.value).selectAll('*').remove();

    // 设置图表尺寸和边距
    const margin = { top: 60, right: 60, bottom: 100, left: 80 }; // 增加了底部边距以容纳三行文本
    const width = chartContainer.value.clientWidth - margin.left - margin.right;
    const height = chartContainer.value.clientHeight - margin.top - margin.bottom;

    // 创建SVG元素
    svg = d3.select(chartContainer.value)
        .append('svg')
        .attr('width', '100%')
        .attr('height', '100%')
        .attr('viewBox', `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`)
        .attr('preserveAspectRatio', 'xMidYMid meet');

    // 添加图表容器并设置偏移
    chart = svg.append('g')
        .attr('transform', `translate(${margin.left}, ${margin.top})`);

    // 获取所有的单位类型
    const unitTypes = [...new Set(props.chartData.map(d => d.unitType))];

    // 数据预处理
    const data = props.chartData.map(d => {
        const unitConsumption = parseFloat(d.unitConsumption) || 0;
        const commonValue = parseFloat(d.commonValue) || 0;
        const advancedValue = parseFloat(d.advancedValue) || 0;

        // 使用默认橙色，不根据值的比较来改变颜色
        const color = '#FAAC58';  // 默认橙色

        return {
            ...d,
            period: d.period,
            area: d.area || '全部',
            unitConsumption: unitConsumption,
            commonValue: commonValue,
            advancedValue: advancedValue,
            label: `${d.period}`,
            displayLabel: `${d.period}${d.unitType}${d.area || '全部'}`,
            color: color
        };
    }).filter(d => !isNaN(d.unitConsumption) && d.unitConsumption > 0);

    // 如果没有有效数据，显示空图表
    if (data.length === 0) {
        svg.append('text')
            .attr('x', chartContainer.value.clientWidth / 2)
            .attr('y', chartContainer.value.clientHeight / 2)
            .attr('text-anchor', 'middle')
            .text('暂无有效数据');
        return;
    }

    // 创建X轴比例尺（类别轴）
    const x = d3.scaleBand()
        .domain(data.map(d => d.label))
        .range([0, width])
        .padding(0.3);

    // 计算实际柱宽并限制最大宽度为120px
    let barWidth = Math.min(x.bandwidth(), 120);

    // 创建Y轴比例尺（线性轴）
    const maxValue = d3.max(data, d =>
        Math.max(d.unitConsumption || 0, d.commonValue || 0, d.advancedValue || 0)
    ) * 1.2; // 多预留20%的空间

    const y = d3.scaleLinear()
        .domain([0, maxValue > 0 ? maxValue : 100]) // 确保Y轴总是有正值范围
        .range([height, 0]);

    // 绘制X轴（只有轴线和刻度，不包含文本）
    chart.append('g')
        .attr('transform', `translate(0, ${height})`)
        .call(d3.axisBottom(x).tickSize(0).tickFormat(''));

    // 为每个柱子添加三行文本标签
    data.forEach((d, i) => {
        // 第一行: period (周期)
        chart.append('text')
            .attr('x', x(d.label) + x.bandwidth() / 2)
            .attr('y', height + 20)
            .attr('text-anchor', 'middle')
            .style('font-size', '12px')
            .text(d.period);

        // 第二行: unitType (单位类型)
        chart.append('text')
            .attr('x', x(d.label) + x.bandwidth() / 2)
            .attr('y', height + 40)
            .attr('text-anchor', 'middle')
            .style('font-size', '12px')
            .text(d.unitType);

        // 第三行: area (区域)
        chart.append('text')
            .attr('x', x(d.label) + x.bandwidth() / 2)
            .attr('y', height + 60)
            .attr('text-anchor', 'middle')
            .style('font-size', '12px')
            .text(d.area || '全部');
    });

    // 绘制Y轴
    chart.append('g')
        .call(d3.axisLeft(y));

    // 添加Y轴标题（单位）
    chart.append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', -60)
        .attr('x', -height / 2)
        .attr('dy', '1em')
        .style('text-anchor', 'middle')
        .text(unitTypes.length === 1 ? unitTypes[0] : '单耗值');

    // 添加图表标题
    svg.append('text')
        .attr('x', (width + margin.left + margin.right) / 2)
        .attr('y', margin.top / 2)
        .attr('text-anchor', 'middle')
        .style('font-size', '16px')
        .text(props.title);

    // 创建提示框
    const tooltip = d3.select(chartContainer.value)
        .append('div')
        .attr('class', 'tooltip')
        .style('opacity', 0)
        .style('position', 'absolute')
        .style('background-color', 'white')
        .style('border', '1px solid #ddd')
        .style('border-radius', '4px')
        .style('padding', '10px')
        .style('pointer-events', 'none');

    // 绘制柱状图，使用最大宽度限制，并居中柱子
    chart.selectAll('.bar')
        .data(data)
        .enter()
        .append('rect')
        .attr('class', 'bar')
        .attr('x', d => x(d.label) + (x.bandwidth() - barWidth) / 2) // 居中柱子
        .attr('width', barWidth) // 使用限制后的宽度
        .attr('y', height)
        .attr('height', 0)
        .attr('fill', d => d.color)
        .on('mouseover', function (event, d) {
            d3.select(this).attr('fill', d3.color(d.color).darker(0.2));
            tooltip.transition()
                .duration(200)
                .style('opacity', .9);

            // 不添加对比结果到提示框
            tooltip.html(`周期: ${d.period}<br/>区域: ${d.area}<br/>单耗: ${d.unitConsumption}<br/>通用值: ${d.commonValue}<br/>先进值: ${d.advancedValue}`)
                .style('left', `${event.pageX}px`)
                .style('top', `${event.pageY - 28}px`);
        })
        .on('mouseout', function (event, d) {
            d3.select(this).attr('fill', d.color);
            tooltip.transition()
                .duration(500)
                .style('opacity', 0);
        })
        .transition()
        .duration(800)
        .delay((d, i) => i * 100)
        .attr('y', d => {
            const yPos = y(d.unitConsumption);
            return Number.isFinite(yPos) ? Math.max(0, yPos) : 0;
        })
        .attr('height', d => {
            const barHeight = height - y(d.unitConsumption);
            return Number.isFinite(barHeight) ? Math.max(0, barHeight) : 0;
        });

    // 给柱子添加数值标签
    chart.selectAll('.value-label')
        .data(data)
        .enter()
        .append('text')
        .attr('class', 'value-label')
        .attr('x', d => x(d.label) + x.bandwidth() / 2)
        .attr('y', height)
        .attr('opacity', 0)
        .attr('text-anchor', 'middle')
        .text(d => d.unitConsumption)
        .transition()
        .duration(800)
        .delay((d, i) => i * 100 + 300)
        .attr('y', d => Math.max(0, y(d.unitConsumption) - 5))
        .attr('opacity', 1);

    // 为每个柱子绘制通用值和先进值参考线
    data.forEach((d, i) => {
        // 绘制通用值线
        if (d.commonValue && d.commonValue > 0) {
            const commonY = y(d.commonValue);
            if (Number.isFinite(commonY)) {
                const commonLine = chart.append('line')
                    .attr('class', 'reference-line')
                    .attr('x1', x(d.label))
                    .attr('y1', commonY)
                    .attr('x2', x(d.label))
                    .attr('y2', commonY)
                    .attr('stroke', '#FF0000')
                    .attr('stroke-width', 1.5)
                    .attr('stroke-dasharray', '5,5')
                    .attr('opacity', 0);

                commonLine.transition()
                    .duration(500)
                    .delay(i * 100 + 600)
                    .attr('x2', x(d.label) + x.bandwidth())
                    .attr('opacity', 1);

                const commonLabel = chart.append('text')
                    .attr('class', 'reference-label')
                    .attr('x', x(d.label) + x.bandwidth() + 5)
                    .attr('y', commonY)
                    .attr('dy', '0.35em')
                    .attr('text-anchor', 'start')
                    .style('font-size', '12px')
                    .style('fill', '#FF0000')
                    .text(d.commonValue)
                    .attr('opacity', 0);

                commonLabel.transition()
                    .duration(500)
                    .delay(i * 100 + 800)
                    .attr('opacity', 1);
            }
        }

        // 绘制先进值线
        if (d.advancedValue && d.advancedValue > 0) {
            const advancedY = y(d.advancedValue);
            if (Number.isFinite(advancedY)) {
                const advancedLine = chart.append('line')
                    .attr('class', 'reference-line')
                    .attr('x1', x(d.label))
                    .attr('y1', advancedY)
                    .attr('x2', x(d.label))
                    .attr('y2', advancedY)
                    .attr('stroke', '#0080FF')
                    .attr('stroke-width', 1.5)
                    .attr('stroke-dasharray', '5,5')
                    .attr('opacity', 0);

                advancedLine.transition()
                    .duration(500)
                    .delay(i * 100 + 600)
                    .attr('x2', x(d.label) + x.bandwidth())
                    .attr('opacity', 1);

                const advancedLabel = chart.append('text')
                    .attr('class', 'reference-label')
                    .attr('x', x(d.label) - 5)
                    .attr('y', advancedY)
                    .attr('dy', '0.35em')
                    .attr('text-anchor', 'end')
                    .style('font-size', '12px')
                    .style('fill', '#0080FF')
                    .text(d.advancedValue)
                    .attr('opacity', 0);

                advancedLabel.transition()
                    .duration(500)
                    .delay(i * 100 + 800)
                    .attr('opacity', 1);
            }
        }
    });

    // 添加图例 - 仅显示虚线的含义
    const legendData = [
        { label: '通用值', color: '#FF0000', type: 'line' },
        { label: '先进值', color: '#0080FF', type: 'line' }
    ];

    // 将图例放在右上角，确保不与图表重叠
    const legend = svg.append('g')
        .attr('class', 'legend')
        .attr('transform', `translate(${width + margin.left - 100}, ${margin.top - 40})`);

    legendData.forEach((item, i) => {
        const legendItem = legend.append('g')
            .attr('transform', `translate(0, ${i * 20})`);

        // 虚线表示通用值和先进值
        legendItem.append('line')
            .attr('x1', 0)
            .attr('y1', 9)
            .attr('x2', 18)
            .attr('y2', 9)
            .attr('stroke', item.color)
            .attr('stroke-width', 1.5)
            .attr('stroke-dasharray', '5,5');

        legendItem.append('text')
            .attr('x', 24)
            .attr('y', 9)
            .attr('dy', '.35em')
            .style('text-anchor', 'start')
            .text(item.label);
    });
};

// 监听数据变化
watch(() => props.chartData, () => {
    createChart();
}, { deep: true });

// 监听窗口大小变化
const handleResize = () => {
    createChart();
};

onMounted(() => {
    window.addEventListener('resize', handleResize);
    createChart();
});

onBeforeUnmount(() => {
    window.removeEventListener('resize', handleResize);
});
</script>

<style scoped>
.consumption-chart-container {
    width: 100%;
    height: 100%;
}

.chart-container {
    width: 100%;
    height: 100%;
}

:deep(.tooltip) {
    position: absolute;
    text-align: left;
    padding: 8px;
    font: 12px sans-serif;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid #aaa;
    border-radius: 4px;
    pointer-events: none;
    z-index: 100;
    box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
}
</style>